# _*_ encoding: utf-8 _*_
import optparse
try:
    import xml.etree.cElementTree as ET
except ImportError:
    import xml.etree.ElementTree as ET
import time


def do_with_block(state, block, buf, current_time):
    for item in block:
        item = item.strip()
        if 0 == state:
            elems = item.split(' ')
            if elems[0] == "<fcd-export":
                state = 1
        else:
            elems = item.split(' ')
            if elems[0] == '<timestep':
                current_time = float(elems[1].split('="')[-1].split('"')[0])
            elif elems[0] == '<vehicle':
                data = parse(item)
                data.setdefault('time', '{0}'.format(current_time))
                buf.append(write_format(data))
    return state, current_time


def convert(xml_file, csv_file):
    count = 0
    with open(xml_file, 'rb') as fp:
        with open(csv_file, 'wb') as fw:
            block = []
            current_time = -1
            state = 0
            buf = []
            for line in fp:
                block.append(line)
                if len(block) == 100000:
                    state, current_time = do_with_block(state, block, buf, current_time)
                    if len(buf) >= 500000:
                        count += len(buf)
                        fw.writelines(buf)
                        del buf
                        buf = []
                    del block
                    block = []
            if len(block) != 0:
                do_with_block(state, block, buf, current_time)
                fw.writelines(buf)
                count += len(buf)
                del block
                del buf
    return count


def parse(line):
    root = ET.fromstring(line)
    return root.attrib


def write_format(data):
    keys = ['id', 'time', 'x', 'y', 'angle', 'type', 'speed', 'pos', 'lane']
    line = ""
    for key in keys:
        line += data[key] + ","
    return line + '\n'


def get_options(args=None):
    optparser = optparse.OptionParser()
    optparser.add_option("-x", "--xml", dest="xfile", help="GPS data in xml format")
    optparser.add_option("-o", "--output", dest="output", help="GPS data in csv format")
    (options, args) = optparser.parse_args(args=args)
    if not options.xfile or not options.output:
        optparser.print_help()
        exit(0)
    return options


def main(options=None):
    # xml_file = "../../data/10221507.gps.xml"
    # csv_file = "../../data/10221507-2.gps.csv"
    # xml_file = "../../data/1030/10301255.gps.xml"
    # csv_file = "../../data/1030/10301255.gps.csv"
    start_CPU = time.clock()
    count = convert(options.xfile, options.output)
    end_CPU = time.clock()
    print "time {0} CPU seconds".format(end_CPU - start_CPU)
    print "generated {0} lines".format(count)

if __name__ == '__main__':
    main(get_options())